#include "../src/parser/sql_parser.h"
#include <stdio.h>
#include <stdlib.h>

static void print_expression(expression_t* expr, int indent);
static void print_statement(statement_t* stmt);

static void print_expression(expression_t* expr, int indent) {
    if (!expr) {
        printf("%*sNULL expression\n", indent, "");
        return;
    }
    
    printf("%*sExpression type: %d\n", indent, "", expr->type);
    
    switch (expr->type) {
        case EXPR_LITERAL:
            printf("%*sLiteral: '%s'\n", indent, "", expr->data.literal.value ? expr->data.literal.value : "NULL");
            break;
        case EXPR_COLUMN:
            printf("%*sColumn: %s.%s\n", indent, "", 
                   expr->data.column.table_name ? expr->data.column.table_name : "",
                   expr->data.column.column_name ? expr->data.column.column_name : "NULL");
            break;
        case EXPR_LIST:
            printf("%*sList with %u items:\n", indent, "", expr->data.list.count);
            for (uint32_t i = 0; i < expr->data.list.count; i++) {
                printf("%*sItem[%u]:\n", indent, "", i);
                print_expression(expr->data.list.expressions[i], indent + 2);
            }
            break;
        case EXPR_BINARY_OP:
            printf("%*sBinary op: %d\n", indent, "", expr->data.binary_op.operator);
            printf("%*sLeft:\n", indent, "");
            print_expression(expr->data.binary_op.left, indent + 2);
            printf("%*sRight:\n", indent, "");
            print_expression(expr->data.binary_op.right, indent + 2);
            break;
        default:
            printf("%*sUnhandled expression type: %d\n", indent, "", expr->type);
            break;
    }
}

static void print_statement(statement_t* stmt) {
    if (!stmt) {
        printf("NULL statement\n");
        return;
    }
    
    printf("Statement type: %d\n", stmt->type);
    
    switch (stmt->type) {
        case STMT_SELECT:
            printf("SELECT List:\n");
            print_expression(stmt->data.select.select_list, 1);
            
            if (stmt->data.select.from_list) {
                printf("FROM:\n");
                table_ref_t* table = stmt->data.select.from_list;
                while (table) {
                    printf("  table: %s\n", table->table_name ? table->table_name : "NULL");
                    if (table->alias) {
                        printf("  alias: %s\n", table->alias);
                    }
                    table = table->next;
                }
            }
            
            if (stmt->data.select.where_clause) {
                printf("WHERE:\n");
                print_expression(stmt->data.select.where_clause, 1);
            }
            
            if (stmt->data.select.order_by) {
                printf("ORDER BY:\n");
                print_expression(stmt->data.select.order_by, 1);
            }
            
            if (stmt->data.select.limit > 0) {
                printf("LIMIT: %u\n", stmt->data.select.limit);
            }
            
            if (stmt->data.select.offset > 0) {
                printf("OFFSET: %u\n", stmt->data.select.offset);
            }
            break;
            
        default:
            printf("Statement details not implemented for this type\n");
            break;
    }
}

static void test_orderby_limit_queries() {
    printf("=== Testing ORDER BY and LIMIT Statements ===\n");
    
    const char* test_queries[] = {
        "SELECT name FROM users ORDER BY name",
        "SELECT id, name FROM users ORDER BY id, name",
        "SELECT * FROM products LIMIT 10",
        "SELECT name FROM users ORDER BY name LIMIT 5",
        "SELECT id, name FROM customers ORDER BY name LIMIT 10 OFFSET 20",
        "SELECT price FROM products WHERE category = 'electronics' ORDER BY price LIMIT 5"
    };
    
    for (size_t i = 0; i < sizeof(test_queries) / sizeof(test_queries[0]); i++) {
        printf("\nTest %zu: %s\n", i + 1, test_queries[i]);
        
        parser_t* parser = parser_create(test_queries[i]);
        if (!parser) {
            printf("Failed to create parser\n");
            continue;
        }
        
        statement_t* stmt = parser_parse_statement(parser);
        
        if (parser_has_error(parser)) {
            printf("Parse error: %s\n", parser_get_error(parser));
        } else if (stmt) {
            printf("Parse successful:\n");
            print_statement(stmt);
            statement_destroy(stmt);
        } else {
            printf("No statement parsed\n");
        }
        
        parser_destroy(parser);
    }
}

int main() {
    printf("GuDB ORDER BY / LIMIT Parser Test\n");
    printf("==================================\n");
    
    test_orderby_limit_queries();
    
    printf("\n=== Tests Completed ===\n");
    return 0;
}